package ca.unbc.cpsc672.plot;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;

import ca.unbc.cpsc672.GUIUtils;
import ca.unbc.cpsc672.fuzzy.FuzzySet;
import ca.unbc.cpsc672.fuzzy.function.MembershipFunction;

public class FunctionPlotWindow {
	private FuzzySet fuzSet;
	private Canvas canvas;

	public FunctionPlotWindow(Composite parent, FuzzySet fuzSet) {
		this.fuzSet = fuzSet;
		canvas = new Canvas(parent, SWT.NONE);
		GridData data = GUIUtils.buildGridData();
		data.heightHint = 200;
		data.widthHint = 400;
		canvas.setLayoutData(data);
	}

	public void redrawPlot(String highlight) {
		canvas.addPaintListener(new DrawPlot(highlight));
		canvas.redraw();
	}

	private final class DrawPlot implements PaintListener {
		private final String highlight;

		private DrawPlot(String highlight) {
			this.highlight = highlight;
		}

		public void paintControl(PaintEvent e) {
			PlotCanvas p = new PlotCanvas((Canvas) e.widget, fuzSet.getRange());
			drawAllCurve(p);
			e.gc.drawImage(p.getImage(), 0, 0);
		}

		private void drawAllCurve(PlotCanvas plot) {
			for (MembershipFunction func : fuzSet.getAllMembershipFunction()) {
				int c = func.getLinguisticVariable().equals(highlight) ? SWT.COLOR_RED
						: SWT.COLOR_BLACK;
				plot.setFGColor(c);
				drawCurve(plot, func);

				int px = plot.calcPixelX(func.getCenter());
				int py = plot.calcPixelY(1) - 10;
				plot.getGC().drawText(func.getLinguisticVariable(), px, py);
			}
		}

		public void drawCurve(PlotCanvas plot, MembershipFunction func) {
			GC gc = plot.getGC();
			int prex = plot.calcPixelX(0);
			int prey = plot.calcPixelY(func.calcProperbility(0));
			double step = plot.getPointPixcelRatio();
			for (double x = step; x < plot.getMaxVal(); x += step) {
				double y = func.calcProperbility(x);
				int px = plot.calcPixelX(x);
				int py = plot.calcPixelY(y);

				if (!(y == 0 && prey == py))
					gc.drawLine(prex, prey, px, py);

				prex = px;
				prey = py;
			}
		}
	}
}
